<template>
  <div style="border: 1px solid #ccc">
    <Toolbar
      style="border-bottom: 1px solid #ccc"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <!-- :defaultConfig="toolbarConfig" 自定义工具栏-->
    <Editor
      style="height: 500px; overflow-y: hidden"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
      @on-change="onChange"
    />
  </div>
</template>
<script setup>
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { onBeforeUnmount, shallowRef, inject } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
const valueHtml = defineModel()
const uploadUrl = inject('uploadUrl')
const token = sessionStorage.getItem('token')
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()
const mode = 'default'
const toolbarConfig = {
  // 插入哪些菜单
  insertKeys: {
    index: 0, // 自定义插入的位置
    keys: ['uploadAttachment'] // “上传附件”菜单
  }
}
const editorConfig = {
  placeholder: '请输入内容...',
  // 在编辑器中，点击选中“附件”节点时，要弹出的菜单
  hoverbarKeys: {
    attachment: {
      menuKeys: ['downloadAttachment', 'convertToLinkCard'] // “下载附件”菜单
    },
    // 在编辑器中，选中链接文本时，要弹出的菜单
    link: {
      menuKeys: [
        'editLink',
        'unLink',
        'viewLink', // 默认的配置可以通过 `editor.getConfig().hoverbarKeys.link` 获取
        'convertToLinkCard' // 增加 '转为链接卡片'菜单
      ]
    }
  },
  MENU_CONF: {
    uploadImage: {
      server: uploadUrl,
      fieldName: 'file',
      headers: {
        token
      },
      customInsert(res, insertFn) {
        // 自定义插入图片
        // TS 语法
        // customInsert(res, insertFn) {                  // JS 语法
        // res 即服务端的返回结果

        // 从 res 中找到 url alt href ，然后插入图片
        insertFn(res.data.url, res.data.url, res.data.url)
      }
    },
    uploadVideo: {
      server: uploadUrl,
      fieldName: 'file',
      headers: {
        token
      },
      customInsert(res, insertFn) {
        // 自定义插入图片
        // TS 语法
        // customInsert(res, insertFn) {                  // JS 语法
        // res 即服务端的返回结果

        // 从 res 中找到 url alt href ，然后插入图片
        insertFn(res.data.url, null)
      }
    },
    // “上传附件”菜单的配置
    uploadAttachment: {
      server: uploadUrl, // 服务端地址
      timeout: 5 * 1000, // 5s
      fieldName: 'file',
      // meta: { token: 'xxx', a: 100 }, // 请求时附加的数据
      metaWithUrl: true, // meta 拼接到 url 上
      headers: {
        token
      },
      maxFileSize: 10 * 1024 * 1024, // 10M
      onBeforeUpload(file) {
        console.log('onBeforeUpload', file)
        return file // 上传 file 文件
        // return false // 会阻止上传
      },
      onProgress(progress) {
        console.log('onProgress', progress)
      },
      onSuccess(file, res) {
        console.log('onSuccess', file, res)
      },
      onFailed(file, res) {
        alert(res.message)
        console.log('onFailed', file, res)
      },
      onError(file, err, res) {
        alert(err.message)
        console.error('onError', file, err, res)
      },

      // 上传成功后，用户自定义插入文件
      customInsert(res, file, insertFn) {
        // 插入附件到编辑器
        insertFn(`customInsert-${file.name}`, res.data.url)
      },

      // // 用户自定义上传
      // customUpload(file: File, insertFn: Function) {
      //   console.log('customUpload', file)

      //   return new Promise(resolve => {
      //     // 插入一个文件，模拟异步
      //     setTimeout(() => {
      //       const src = `https://www.w3school.com.cn/i/movie.ogg`
      //       insertFn(`customUpload-${file.name}`, src)
      //       resolve('ok')
      //     }, 500)
      //   })
      // },

      // // 自定义选择
      // customBrowseAndUpload(insertFn: Function) {
      //   alert('自定义选择文件，如弹出图床')
      //   // 自己上传文件
      //   // 上传之后用 insertFn(fileName, link) 插入到编辑器
      // },

      // 插入到编辑器后的回调
      onInsertedAttachment(elem) {
        console.log('inserted attachment', elem)
      }
    },
    // '转为链接卡片'菜单的配置
    convertToLinkCard: {
      // 自定义获取 link-card 信息，可选
      // 返回 { title, iconImgSrc }
      async getLinkCardInfo(linkText, linkUrl) {
        // 1. 可通过 iframe 加载网页，然后获取网页 title 和其中的图片
        // 2. 服务端获取（有些网页会设置 `X-Frame-Options` ，无法通过 iframe 加载）
        // // 模拟异步返回
        return new Promise((resolve) => {
          setTimeout(() => {
            const info = { title: linkText, iconImgSrc: '' }
            resolve(info)
          }, 100)
        })
      }
    }
  }
}
function onChange(editor) {}

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

function handleCreated(editor) {
  editorRef.value = editor // 记录 editor 实例，重要！
}
</script>
<style scoped>
:deep(.w-e-select-list) {
  top: -290px;
}
/**渲染链接卡片 */
div[data-w-e-type='link-card'] {
  width: 450px;
  margin: 0 auto;
  background-color: #f1f1f1;
  border-radius: 10px;
  display: flex;
  padding: 10px 20px;
  cursor: pointer;
}
div[data-w-e-type='link-card'] .info-container {
  flex: 1;
  padding-right: 20px;
}
div[data-w-e-type='link-card'] .info-container p {
  margin-top: 5px;
  font-weight: bold;
}
div[data-w-e-type='link-card'] .info-container span {
  opacity: 0.5;
}
div[data-w-e-type='link-card'] .icon-container {
  width: 64px;
  overflow: hidden;
}
div[data-w-e-type='link-card'] .icon-container img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
</style>
